package com.sunwayworld.basemodule.rm.materialsecondarylibrary.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.sunwayworld.basemodule.common.constant.LimsConstant;
import com.sunwayworld.basemodule.rm.materialsecondarylibrary.bean.LimsMaterialSecondaryHistoryBean;
import com.sunwayworld.basemodule.rm.materialsecondarylibrary.bean.LimsMaterialSecondaryLibraryBean;
import com.sunwayworld.basemodule.rm.materialsecondarylibrary.service.LimsMaterialSecondaryHistoryService;
import com.sunwayworld.basemodule.rm.materialsecondarylibrary.service.LimsMaterialSecondaryLibraryService;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.spring.annotation.GikamBean;

import com.sunwayworld.basemodule.rm.materialsecondarylibrary.dao.LimsMaterialSecondaryInventoryDao;
import com.sunwayworld.basemodule.rm.materialsecondarylibrary.bean.LimsMaterialSecondaryInventoryBean;
import com.sunwayworld.basemodule.rm.materialsecondarylibrary.service.LimsMaterialSecondaryInventoryService;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;

import java.time.LocalDateTime;

@Repository
@GikamBean
public class LimsMaterialSecondaryInventoryServiceImpl implements LimsMaterialSecondaryInventoryService {

    @Autowired
    private LimsMaterialSecondaryInventoryDao limsMaterialSecondaryInventoryDao;

    @Autowired
    @Lazy
    private LimsMaterialSecondaryLibraryService limsMaterialSecondaryLibraryService;

    @Autowired
    @Lazy
    private LimsMaterialSecondaryHistoryService limsMaterialSecondaryHistoryService;

    @Override
    @SuppressWarnings("unchecked")
    public LimsMaterialSecondaryInventoryDao getDao() {
        return limsMaterialSecondaryInventoryDao;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsMaterialSecondaryInventoryBean limsMaterialSecondaryInventory = jsonWrapper.parseUnique(LimsMaterialSecondaryInventoryBean.class);
        limsMaterialSecondaryInventory.setId(ApplicationContextHelper.getNextIdentity());
        getDao().insert(limsMaterialSecondaryInventory);
        return limsMaterialSecondaryInventory.getId();
    }

    @Override
    @Transactional
    public JSONObject inventory(RestJsonWrapperBean wrapperBean) {
        JSONObject req = new JSONObject();

        String difference = wrapperBean.getParamValue("difference");
        double differenceNum = Double.parseDouble(wrapperBean.getParamValue("differenceNum"));
        String remark = wrapperBean.getParamValue("remark");
        LimsMaterialSecondaryInventoryBean inventoryBean = wrapperBean.parseUnique(LimsMaterialSecondaryInventoryBean.class);
        if (StringUtils.isBlank(difference) || differenceNum == 0D || inventoryBean == null || inventoryBean.getId() == null) {
            return req;
        }
        LimsMaterialSecondaryInventoryBean realBean = this.selectFirstByFilter(SearchFilter.instance().match("id", inventoryBean.getId()).filter(MatchPattern.EQ));
        LimsMaterialSecondaryLibraryBean libraryBean = limsMaterialSecondaryLibraryService.selectFirstByFilter(SearchFilter.instance().match("id", inventoryBean.getMatSecondId()).filter(MatchPattern.EQ));
        if (realBean == null || libraryBean == null) {
            req.put("message", "未找到材料信息，请重试！");
            return req;
        }

        // 新增库存记录
        LimsMaterialSecondaryHistoryBean historyBean = new LimsMaterialSecondaryHistoryBean();
        historyBean.setId(ApplicationContextHelper.getNextIdentity());
        historyBean.setSecondInventoryId(realBean.getId());
        historyBean.setCompleteTime(LocalDateTime.now());
        historyBean.setQuantity(differenceNum);
        historyBean.setStatus("完成");
        historyBean.setRemark(remark);
        if (LimsConstant.MATERIAL_FLAG_INVENTORY_ADD.equalsIgnoreCase(difference)) {
            // 盘存+
            realBean.setBatchNum(realBean.getBatchNum() + differenceNum);
            libraryBean.setMatNum(libraryBean.getMatNum() + differenceNum);
            historyBean.setOperation(LimsConstant.MATERIAL_OPERATION_INVENTORY_ADD);
        } else {
            // 盘存-
            realBean.setBatchNum(realBean.getBatchNum() - differenceNum);
            libraryBean.setMatNum(libraryBean.getMatNum() - differenceNum);
            historyBean.setOperation(LimsConstant.MATERIAL_OPERATION_INVENTORY_SUBTRACT);

            if (realBean.getBatchNum() < 0 || libraryBean.getMatNum() < 0) {
                throw new InvalidDataException("批次库存数量不足！");
            }
        }
        this.getDao().update(realBean, "batchNum");
        limsMaterialSecondaryLibraryService.getDao().update(libraryBean, "matNum");
        limsMaterialSecondaryHistoryService.getDao().insert(historyBean);

        return req;
    }

    @Override
    @Transactional
    public JSONObject checkout(RestJsonWrapperBean wrapperBean) {
        JSONObject req = new JSONObject();

        String isoutoperation = wrapperBean.getParamValue("isoutoperation");
        String issueType = wrapperBean.getParamValue("issueType");
        double outNum = Double.parseDouble(wrapperBean.getParamValue("outNum"));
        LimsMaterialSecondaryInventoryBean inventoryBean = wrapperBean.parseUnique(LimsMaterialSecondaryInventoryBean.class);
        if (StringUtils.isBlank(issueType) || outNum == 0D || inventoryBean == null || inventoryBean.getId() == null) {
            return req;
        }
        LimsMaterialSecondaryInventoryBean realBean = this.selectFirstByFilter(SearchFilter.instance().match("id", inventoryBean.getId()).filter(MatchPattern.EQ));
        LimsMaterialSecondaryLibraryBean libraryBean = limsMaterialSecondaryLibraryService.selectFirstByFilter(SearchFilter.instance().match("id", inventoryBean.getMatSecondId()).filter(MatchPattern.EQ));
        if (realBean == null || libraryBean == null) {
            req.put("message", "未找到材料信息，请重试！");
            return req;
        }

        // 材料二级库管理界面直接出库
        if (StringUtils.isBlank(isoutoperation) || "1".equals(isoutoperation)) {
            if (realBean.getBatchNum() < outNum) {
                req.put("message", "BASEMODULE.RM.MATERIALS.TIP.OUTNUM.TOOBIG");
                return req;
            }
            // 出库后的数量
            realBean.setBatchNum(realBean.getBatchNum() - outNum);
            libraryBean.setMatNum(libraryBean.getMatNum() - outNum);
            this.getDao().update(realBean, "batchNum");
            limsMaterialSecondaryLibraryService.getDao().update(libraryBean, "matNum");

            // 新增库存记录
            LimsMaterialSecondaryHistoryBean historyBean = new LimsMaterialSecondaryHistoryBean();
            historyBean.setId(ApplicationContextHelper.getNextIdentity());
            historyBean.setSecondInventoryId(realBean.getId());
            historyBean.setCompleteTime(LocalDateTime.now());
            historyBean.setQuantity(outNum);
            historyBean.setOperation(LimsConstant.MATERIAL_OPERATION_TAKE);
            historyBean.setStatus("完成");
            historyBean.setIssueType(issueType);

            limsMaterialSecondaryHistoryService.getDao().insert(historyBean);
        }
        return req;
    }
}
